/*!
* @file    image_data.c
* @version v1.0
* @date    2018-02-05
* @author  苏勇 suyong_yq@126.com
* @brief   对图像数据进行预处理
*/

/*
* 主要实现对原始数据的压缩。
* 考虑到对摄像头数据的处理多是以行进行遍历，并且二值化的灰度值仅用1比特就能表示一个像素，因此将行数据压缩，
* 可使用32位数直接表示32个像素。
* 在压缩数据的情况下，取单个像素会比较麻烦，因此也可以提供专门的函数
* 后期若为了提高处理速度，可以用映射算法，用空间换时间，直接以32位字作为单位处理像素，充分发挥32位处理器的带宽
*/
#include "image.h"

/* u32Image在输入时仅指定缓冲区开始地址，在函数执行结束后所有字段均被更新
 */
uint32_t Image_CopyToBinaryImage(
    Image_GrayImageHandle_T   *u8Image,
    Image_BinaryImageHandle_T *u32Image,
    uint8_t  thresh  /* 二值化阈值 */  )
{
    uint32_t u8Idx, u32Idx;
    uint32_t i;
    uint32_t u32Tmp;

    uint32_t lineIdx;
    uint8_t  *u8Pixels  = u8Image->u8Pixels;
    uint32_t *u32Pixels = u32Image->u32Pixels;

    u32Image->LineMax = u8Image->LineMax;
    u32Image->RowMax  = u8Image->RowMax >> 5U; /* u32能保留的像素小于等于u8的像素 */

    for (lineIdx = 0U; lineIdx < u32Image->LineMax; lineIdx++) /* 遍历每个像素行 */
    {
        u8Pixels = (lineIdx * u8Image->RowMax); /* u8Pixels为一行像素的起点 */
        for (u32Idx = 0U; u32Idx < u32Image->RowMax; u32Idx++) /* 遍历每个压缩像素 */
        {
            u32Tmp = 0U;
            i = 0U;
            while (i < 32U) /* 压缩单个数据 */
            {
                if ((*u8Pixels) > thresh)
                {
                    u32Tmp |= 1U;
                }
                u32Tmp = u32Tmp << 1U;
                u8Pixels++;
                i++;
            }
            *u32Pixels++ = u32Tmp;
        }
    }
    return u32Image->RowMax;
}

/* 从压缩图像中取出一个像素 */
uint8_t Image_GetBinaryPixelValue(Image_BinaryImageHandle_T *u32Image, uint32_t lineIdx, uint32_t binRowIdx)
{
    uint32_t *u32Pixels = u32Image->u32Pixels;
    uint32_t u32RowIdx = binRowIdx >> 5U;

    binRowIdx = binRowIdx & 0x1F;

    if (0U == ( (1U << binRowIdx) & u32Pixels[lineIdx * u32Image->RowMax + u32RowIdx]) )
    {
        return 0U;
    }
    else
    {
        return 1U;
    }
}

/* EOF. */

